package rexsee.core.animation;

import rexsee.core.browser.Browser;
import rexsee.core.browser.clazz.JavascriptInterface;
import rexsee.core.browser.clazz.PageBeforeStartListeners.PageBeforeStartListener;
import rexsee.core.browser.clazz.PageReadyListeners.PageReadyListener;
import rexsee.core.browser.clazz.StopListeners.StopListener;
import rexsee.core.utilities.Utilities;
import rexsee.core.widget.Div;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.widget.FrameLayout;

public class RexseeTransition implements JavascriptInterface {

	public static final String INTERFACE_NAME = "Transition";
	@Override
	public String getInterfaceName() {
		return mBrowser.application.resources.prefix + INTERFACE_NAME;
	}
	@Override
	public JavascriptInterface getInheritInterface(Browser childBrowser) {
		return new RexseeTransition(childBrowser);
	}
	@Override
	public JavascriptInterface getNewInterface(Browser childBrowser) {
		return new RexseeTransition(childBrowser);
	}

	public static final String EVENT_ONPAGEANIMATIONSTART = "onPageAnimationStart";
	public static final String EVENT_ONPAGEANIMATIONREPEAT = "onPageAnimationRepeat";
	public static final String EVENT_ONPAGEANIMATIONEND = "onPageAnimationEnd";

	private final Activity mActivity;
	private final Browser mBrowser;
	private AnimationStyleSheet mStyleSheet = null;
	private String mPostStyleText = null;
	private boolean mEnable = false;

	private Div getPageDiv() {
		return mBrowser.containerDiv;
	}
	private final AnimationListener mAnimationListener = new AnimationListener() {
		@Override
		public void onAnimationStart(Animation animation) {
			Utilities.playSound(mActivity, mStyleSheet.animation_start_sound);
			if (mPostStyleText != null) {
				AnimationStyleSheet postStyleSheet = new AnimationStyleSheet(mBrowser).parseStyle(mPostStyleText);
				Div mDiv = getPageDiv();
				if (mDiv == null) return;
				if (!postStyleSheet.animation_post_start.equalsIgnoreCase("start")) {
					mDiv.setStyleWithoutLayoutParams("inner-visibility:hidden;background-color:" + mStyleSheet.background_color + ";");
				}
			}
			mBrowser.eventList.run(EVENT_ONPAGEANIMATIONSTART);
		}
		@Override
		public void onAnimationRepeat(Animation animation) {
			Utilities.playSound(mActivity, mStyleSheet.animation_repeat_sound);
			mBrowser.eventList.run(EVENT_ONPAGEANIMATIONREPEAT);
		}
		@Override
		public void onAnimationEnd(Animation animation) {
			hide();
			Utilities.playSound(mActivity, mStyleSheet.animation_end_sound);
			if (mPostStyleText != null) {
				Div mDiv = getPageDiv();
				if (mDiv == null) return;
				AnimationStyleSheet postStyleSheet = new AnimationStyleSheet(mBrowser).parseStyle(mPostStyleText);
				if (!postStyleSheet.animation_post_start.equalsIgnoreCase("start")) {
					mDiv.setStyleWithoutLayoutParams("inner-visibility:visible;background-color:" + postStyleSheet.background_color + ";");
					postStyleSheet.animate(mDiv.mHorizontalLayout);
				}
			}
			mBrowser.eventList.run(EVENT_ONPAGEANIMATIONEND);
		}
	};
	private final StopListener mStopListener = new StopListener() {
		@Override
		public void run(Context context, Browser browser, String url) {
			hide();
		}
	};

	private final PageBeforeStartListener mStartListener = new PageBeforeStartListener() {
		private boolean syncTag = false;
		@Override
		public void run(Browser browser, String url) {
			syncTag = false;
			mActivity.runOnUiThread(new Runnable() {
				@Override
				public void run() {
					hide();
					if (mStyleSheet == null) return;
					try {
						Div mDiv = getPageDiv();
						if (mDiv == null) {
							syncTag = true;
							return;
						}
						Bitmap bitmap = Utilities.getBitmap(mBrowser, mDiv);
						if (bitmap == null) {
							syncTag = true;

							return;
						}
						final BitmapDrawable drawable = new BitmapDrawable(bitmap);
						FrameLayout cover = mDiv.coverLayout;
						cover.clearAnimation();
						cover.removeAllViews();
						cover.setBackgroundDrawable(drawable);
						cover.setVisibility(View.VISIBLE);
						syncTag = true;
					} catch (Exception e) {
						syncTag = true;
						mBrowser.exception(getInterfaceName(), "Page start error: " + e.getLocalizedMessage());
					}
				}
			});
			while (!syncTag) {
				try {
					Thread.sleep(100);
				} catch (Exception e) {
				}
			}
		}
	};
	private final PageReadyListener mReadyListener = new PageReadyListener() {
		@Override
		public void run(Context context, Browser browser, String url) {
			mActivity.runOnUiThread(new Runnable() {
				@Override
				public void run() {
					mBrowser.progressDialog.hide();
					if (mStyleSheet == null) return;
					try {
						Div mDiv = getPageDiv();
						if (mDiv == null) return;
						if (mPostStyleText != null) {
							AnimationStyleSheet postStyleSheet = new AnimationStyleSheet(mBrowser).parseStyle(mPostStyleText);
							if (postStyleSheet.animation_post_start.equalsIgnoreCase("start")) {
								mDiv.setStyleWithoutLayoutParams("inner-visibility:visible;background-color:" + postStyleSheet.background_color + ";");
								mDiv.setCoverToTop((postStyleSheet.animation_post_z.equalsIgnoreCase("reverse")) ? false : true);
								postStyleSheet.animate(mDiv.mHorizontalLayout);
							} else {
							}
						}
						mStyleSheet.animate(mDiv.coverLayout, mAnimationListener);
					} catch (Exception e) {
						mBrowser.exception(getInterfaceName(), "Page ready error: " + e.getLocalizedMessage());
					}
					if (!mStyleSheet.animation_repeat.equalsIgnoreCase("repeat")) disable();
				}
			});
		}
	};

	public RexseeTransition(Browser browser) {
		super();
		mBrowser = browser;
		mActivity = (Activity) browser.getContext();
		mBrowser.eventList.add(EVENT_ONPAGEANIMATIONSTART);
		mBrowser.eventList.add(EVENT_ONPAGEANIMATIONREPEAT);
		mBrowser.eventList.add(EVENT_ONPAGEANIMATIONEND);
	}

	//JavaScript Interface

	public void setStyle(String style) {
		if (mStyleSheet == null) mStyleSheet = new AnimationStyleSheet(mBrowser);
		mStyleSheet.parseStyle(style);
	}
	public String getStyle(String name) {
		if (mStyleSheet == null) return "";
		return mStyleSheet.getStyle(name);
	}
	public void clearStyle() {
		mStyleSheet = null;
	}
	public boolean hasAnimation() {
		return !(mStyleSheet == null);
	}

	public void setPostStyle(String style) {
		if (mPostStyleText == null) mPostStyleText = "";
		mPostStyleText += style;
	}
	public String getPostStyle() {
		if (mPostStyleText == null) return "";
		return mPostStyleText;
	}
	public void clearPostStyle() {
		mPostStyleText = null;
	}

	public void load(String url, String style) {
		disable();
		setStyle(style + ";animation-repeat:none;");
		enable();
		mBrowser.function.load(url);
	}
	public boolean isEnabled() {
		return mEnable;
	}
	public void enable() {
		hide();
		disable();
		if (!hasAnimation()) {
			mBrowser.exception(getInterfaceName(), "Invalid animation.");
		}
		mBrowser.pageBeforeStartListeners.add(mStartListener);
		mBrowser.pageReadyListeners.add(mReadyListener);
		mBrowser.stopListeners.add(mStopListener);
		mEnable = true;
	}
	public void disable() {
		mBrowser.pageBeforeStartListeners.remove(mStartListener);
		mBrowser.stopListeners.remove(mStopListener);
		mBrowser.pageReadyListeners.remove(mReadyListener);
		mEnable = false;
	}

	public void hide() {
		mActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				try {
					FrameLayout cover = mBrowser.containerDiv.coverLayout;
					cover.clearAnimation();
					cover.removeAllViews();
					cover.setBackgroundDrawable(null);
					cover.setVisibility(View.GONE);
				} catch (Exception e) {
				}
			}
		});
	}

}
